﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Mapack;

namespace QProg
{
	public static class GeneratorForMathematica
	{
		public static void Generate(Matrix D, Matrix X, Matrix C, Matrix A, double[] dmin, double[] dmax, int size)
		{
			StringBuilder strB = new StringBuilder("");
			#region GenerateForD
			strB.Append("varD = {{");
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					strB.Append(String.Format("{0},", D[i, j]));

				}
				strB.Remove(strB.Length - 1, 1);
				strB.Append("},{");
			}
			strB.Remove(strB.Length - 2, 2);
			strB.Append("};\n");
			#endregion

			#region GenerateForA
			strB.Append("varA = {{");
			for (int i = 0; i < A.Rows; i++)
			{
				for (int j = 0; j < A.Columns; j++)
				{
					strB.Append(String.Format("{0},", A[i, j]));

				}
				strB.Remove(strB.Length - 1, 1);
				strB.Append("},{");
			}
			strB.Remove(strB.Length - 2, 2);
			strB.Append("};\n");
			#endregion

			#region GenerateForC
			strB.Append("varC = {");
			for (int i = 0; i < size; i++)
			{
				strB.Append("{");
				strB.Append(C[i, 0]);
				strB.Append("},");
			}

			strB.Remove(strB.Length - 1, 1);
			strB.Append("};\n");

			#endregion

			#region GenerateForFunc
			strB.Append("func[");

			for (int i = 0; i < size; i++)
			{
				strB.Append(String.Format("x{0}_,", i + 1));
			}
			strB.Remove(strB.Length - 1, 1);
			strB.Append("]:=(0.5*Transpose[");

			strB.Append("{");
			for (int i = 0; i < size; i++)
			{
				strB.Append("{");
				strB.Append(String.Format("x{0}", i + 1));
				strB.Append("},");
			}

			strB.Remove(strB.Length - 1, 1);
			strB.Append("}].varD.");
			strB.Append("{");
			for (int i = 0; i < size; i++)
			{
				strB.Append("{");
				strB.Append(String.Format("x{0}", i + 1));
				strB.Append("},");
			}

			strB.Remove(strB.Length - 1, 1);
			strB.Append("}+Transpose[varC].");
			strB.Append("{");
			for (int i = 0; i < size; i++)
			{
				strB.Append("{");
				strB.Append(String.Format("x{0}", i + 1));
				strB.Append("},");
			}

			strB.Remove(strB.Length - 1, 1);
			strB.Append("}+");

			for (int i = 0; i < A.Rows; i++)
			{
				strB.Append(String.Format("Exp[varA[[{0}]]", i + 1));
				strB.Append(".{");
				for (int j = 0; j < A.Columns; j++)
				{
					strB.Append("{");
					strB.Append(String.Format("x{0}", j + 1));
					strB.Append("},");
				}
				strB.Remove(strB.Length - 1, 1);
				strB.Append("}]+");
			}
			strB.Remove(strB.Length - 1, 1);

			strB.Append(")[[1,1]];\n");
			#endregion

			#region GenerateCondition

			strB.Append("Minimize[{func[");

			for (int i = 0; i < size; i++)
			{
				strB.Append(String.Format("x{0},", i + 1));
			}
			strB.Remove(strB.Length - 1, 1);
			strB.Append("],");

			for (int i = 0; i < size; i++)
			{
				strB.Append(String.Format("x{0}>={1} && x{0}<={2} &&", i + 1, dmin[i], dmax[i]));
			}
			strB.Remove(strB.Length - 2, 2);
			strB.Append("}, {");

			for (int i = 0; i < size; i++)
			{
				strB.Append(String.Format("x{0},", i + 1));
			}
			strB.Remove(strB.Length - 1, 1);
			strB.Append("}]");
			#endregion

			using (StreamWriter sw = new StreamWriter(@"mathematica.txt"))
			{
				sw.WriteLine(strB.ToString());
			}

		}
	}
}
